package studiodiva.portfolio.client.view.viewer;

import static com.google.gwt.query.client.GQuery.$;
import static com.google.gwt.query.client.GQuery.$$;

import com.google.gwt.core.client.GWT;
import com.google.gwt.query.client.Function;
import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;

import static studiodiva.portfolio.client.lib.lang.Lang.is;
import static studiodiva.portfolio.client.lib.lang.Lang.no;

import studiodiva.portfolio.client.lib.even.EventFunction;
import studiodiva.portfolio.client.lib.view.LinkButton;
import studiodiva.portfolio.client.lib.view.View;
import studiodiva.portfolio.client.model.HasApplication;
import studiodiva.portfolio.client.model.titles.Page;
import studiodiva.portfolio.client.model.titles.Title;
import studiodiva.portfolio.client.model.titles.Titles;
import studiodiva.portfolio.client.model.titles.Titles.TitleType;
import studiodiva.portfolio.client.view.pages.ContactViewProvider;
import studiodiva.portfolio.client.view.pages.PageViewProvider;

public class ViewerWidget extends View<IsWidget> {

  interface Binder extends UiBinder<Widget, ViewerWidget> {}

  static Binder uiBinder = GWT.create(Binder.class);

  private static final int HEIGHT = 430;

  @UiField
  LinkButton backButton;
  @UiField
  LinkButton nextButton;
  @UiField
  HTML pageNumberInfo;
  @UiField
  PageViewer viewer;
  private boolean opened;
  private Title title;

  public ViewerWidget() {
    initWidget(uiBinder.createAndBindUi(this));
    setVisible(false);
    setHeight(0);
  }

  @Override
  public void initialize(HasApplication hasApplication) {
    super.initialize(hasApplication);
    viewer.initialize(hasApplication);
    getApplication().getTitles().addHandler(Titles.ON_CHANGE, new EventFunction<Title>() {
      public void run(Title value) {
        update(value);
      }
    });
    update(getApplication().getTitles().getOpened());
  }

  private void close() {
    title = null;
    $(asWidget()).animate($$("height:'-=" + HEIGHT + "'"), NORMAL_ANIMATION, Easing.SWING,
        new Function() {
          @Override
          public void f() {
            setVisible(false);
            viewer.close();
          }
        });
    opened = false;
  }

  private boolean isBackVisible() {
    return title.getCurrentIndex() > 0;
  }

  private boolean isNextVisible() {
    return title.getPageCount() > title.getCurrentIndex() + 1;
  }

  private void onPageChange() {
    nextButton.setVisible(isNextVisible());
    if (isNextVisible())
      nextButton.setTarget("page=" + title.getPage(title.getCurrentIndex() + 1).getId());

    backButton.setVisible(isBackVisible());
    if (isBackVisible())
      backButton.setTarget("page=" + title.getPage(title.getCurrentIndex() - 1).getId());

    pageNumberInfo.setVisible(title.getPageCount() > 1);
    pageNumberInfo.setHTML(title.getCurrentIndex() + 1 + "/" + title.getPageCount());
  }

  private void open() {
    $(asWidget()).animate($$("height:'+=" + HEIGHT + "'"), NORMAL_ANIMATION, Easing.SWING);
    opened = true;
  }

  private void update(Title title) {
    this.title = title;
    if (no(title) && opened)
      close();
    else if (is(title)) {
      registerReplaceByEvent(title, Title.ON_PAGE_CHANGE, new EventFunction<Page>() {
        public void run(Page value) {
          onPageChange();
        }
      });
      if (title.getType() == TitleType.contact)
        viewer.open(new ContactViewProvider(title));
      else viewer.open(new PageViewProvider(title));
      onPageChange();
      if (!opened) open();
    }
  }

}
